import unittest
from pygo1963.network_game.GTPEngine import GTPEngine
from pygo1963.model.Player import RandomPlayer
from pygo1963.model import Constants
from pygo1963.model.Vertex import Vertex


class GTPEngineTest(unittest.TestCase):

    def setUp(self):
        self.engine = GTPEngine(RandomPlayer(Constants.BLACK_COLOR, 'random'))

    def test_unknown_command(self):
        response = self.engine.process_command('pepelemoko B15')        
        self.assertEquals(response, '? unknown command\n\n')
        
        response = self.engine.process_command('10 pierrotlefou B15')
        self.assertEquals(response, '?10 unknown command\n\n')
    
    def test_protocol_version(self):
        response = self.engine.process_command('protocol_version')        
        self.assertEquals(response, '= 2\n\n')
        
        response = self.engine.process_command('7 protocol_version')
        self.assertEquals(response, '=7 2\n\n')
    
    def test_name(self):
        response = self.engine.process_command('6 name')
        self.assertTrue(response.startswith('=6 '))
        self.assertTrue(response.endswith('\n\n'))
    
    def test_known_command(self):
        response = self.engine.process_command('5 known_command name')
        self.assertEquals(response, '=5 true\n\n')
        
        response = self.engine.process_command('13 known_command luisao')
        self.assertEquals(response, '=13 false\n\n')
        
        response = self.engine.process_command('known_command')
        self.assertEquals(response, '= false\n\n')
    
    def test_list_commands(self):
        response = self.engine.process_command('12 list_commands')
        
        self.assertTrue(response.startswith('=12 '))
        self.assertTrue(response.endswith('\n\n'))
        
        response = response[4:-2]
        cmd_list = response.split('\n')
        
        self.assertTrue('name' in cmd_list)
        self.assertTrue('protocol_version' in cmd_list)
    
    def test_quit(self):
        
        self.assertFalse(self.engine.received_quit)
        
        response = self.engine.process_command('quit')
        
        self.assertEquals(response, '=\n\n')
        self.assertTrue(self.engine.received_quit)
    
    def test_boardsize(self):
        response = self.engine.process_command('boardsize')        
        self.assertEquals(response, '? sintax error\n\n')
        
        response = self.engine.process_command('boardsize asd')        
        self.assertEquals(response, '? sintax error\n\n')
        
        response = self.engine.process_command('boardsize 1')        
        self.assertEquals(response, '? unacceptable size\n\n')
        
        response = self.engine.process_command('boardsize 30')        
        self.assertEquals(response, '? unacceptable size\n\n')
        
        response = self.engine.process_command('boardsize 15')        
        self.assertEquals(response, '=\n\n')
        self.assertEquals(self.engine.board.size, 15)
        
        response = self.engine.process_command('boardsize 25')        
        self.assertEquals(response, '=\n\n')
        self.assertEquals(self.engine.board.size, 25)    
    
    def test_play(self):
        response = self.engine.process_command('play')
        self.assertEquals(response, '? sintax error\n\n')
        
        response = self.engine.process_command('play white')
        self.assertEquals(response, '? sintax error\n\n')
        
        response = self.engine.process_command('play pepe')
        self.assertEquals(response, '? sintax error\n\n')
        
        response = self.engine.process_command('play black B')
        self.assertEquals(response, '? sintax error\n\n')
        
        response = self.engine.process_command('play black 3')
        self.assertEquals(response, '? sintax error\n\n')
        
        #valid moves
        response = self.engine.process_command('play black B3')        
        self.assertEquals(response, '=\n\n')
        
        response = self.engine.process_command('play black pass')        
        self.assertEquals(response, '=\n\n')
        
        #already played
        response = self.engine.process_command('play black B3')
        self.assertEquals(response, '? illegal move\n\n')
        
        #out of board
        self.engine.process_command('boardsize 4')
        
        response = self.engine.process_command('play black F3')
        self.assertEquals(response, '? illegal move\n\n')
        
        response = self.engine.process_command('play black B6')
        self.assertEquals(response, '? illegal move\n\n')
    
    def test_genmove(self):
        response = self.engine.process_command('genmove black')
        
        self.assertTrue(response.startswith('= '))
        self.assertTrue(response.endswith('\n\n'))
        
        vertex_str = response[2:-2]
                
        try:
            vertex = Vertex.from_string(vertex_str)
        except:
            self.fail("Wrong move")
        
    
    def test_clear_board(self):
        self.engine.process_command('play black B3')                
        response = self.engine.process_command('clear_board')
        self.assertEquals(response, '=\n\n')
        
        #tries the same move
        response = self.engine.process_command('play black B3')
        self.assertEquals(response, '=\n\n')
    
    def test_undo(self):
        response = self.engine.process_command('undo')
        self.assertEquals(response, '? cannot undo\n\n')
        
        self.engine.process_command('play black B3')
        response = self.engine.process_command('undo')
        self.assertEquals(response, '=\n\n')
        
        #replays
        response = self.engine.process_command('play black B3')
        self.assertEquals(response, '=\n\n')
    
    def test_captures(self):
        
        response = self.engine.process_command('captures w')
        self.assertEquals(response, '= 0\n\n')
        
        self.engine.process_command('play w a2')
        self.engine.process_command('play b a1')
        self.engine.process_command('play w b1')
        
        response = self.engine.process_command('captures w')
        self.assertEquals(response, '= 1\n\n')
        
        self.engine.process_command('clear_board')
        
        response = self.engine.process_command('captures b')
        self.assertEquals(response, '= 0\n\n')
        
        self.engine.process_command('play b a2')
        self.engine.process_command('play w a1')
        self.engine.process_command('play b b1')
        
        response = self.engine.process_command('captures b')
        self.assertEquals(response, '= 1\n\n')


if __name__ == "__main__":
    #import sys;sys.argv = ['', 'Test.testName']
    unittest.main()